在 Go 語言中,我們可以使用核心型別作為基礎,來建制自訂型別,且自訂型別擁有本來核心型別的零值,也可以跟同型別的資料做比較,但是自訂型別不能跟本來的核心型別做比較,除非我們有先做型別轉換(後面會教到如何型別轉換)。自訂顧名思義-自己定義,我們可以自己對這個型別加上自訂的函式或方法,這是原始核心型別做不到的。
type <自訂型別名稱> <核心型別>
例:想以字串作為基礎,建立一個名為 myLove
的自訂型別,如下:
type myLove string
範例 1:
package main
import "fmt"
type myLove string // 定義一個自訂型別
func getMyLoves() (myLove, myLove, myLove) {
var myFirstLove myLove = "奇犽" // 將自訂型別建立變數
var mySecondLove myLove // 自訂型別也擁有零值,所以這邊會是空字串
var myLastLove myLove
myLastLove = "奇犽"
return myFirstLove, mySecondLove, myLastLove
}
func main() {
myFirstLove, mySecondLove, myLastLove := getMyLoves()
fmt.Println("我的初戀:", myFirstLove, " 我的第二個戀人:", mySecondLove, " 我最後的愛:", myLastLove) // 印出自訂型別的值
fmt.Println(myFirstLove == mySecondLove) // 比對自訂型別的值
fmt.Println(myFirstLove == myLastLove)
}
範例 1(執行結果):
我的初戀: 奇犽 我的第二個戀人: 我最後的愛: 奇犽
false
true
補充:
在 Go 語言中我們經常看到大家用自訂型別來包裝資料,如此一來將型別名稱自訂為你的資料名稱,可以讓程式碼更好理解、閱讀及接手的人可以更好維護。
上面一個範例我們學習到如何自定一個型別,但是有時候我們並不需要真的建立一個型別,而是只需要給型別一個別名 (alias) ,來讓我們更方便的使用它,如此一來並不會創造新的型別,但你也還是可以使用自己取的別名名稱來使用該型別。
type <別名> = <型別>
例: type id = int
會讓 int 型別多一個 id 的別名,你可以把 id 當成 int 使用,而 id 仍然是 int 的型別沒錯。
先前我們學習的陣列、切片、 map 都可以用來把相同型別的資料放在一起,但有時候你的資料內容又會更複雜化,光是數字、字串已經不足以處理你的資料,這時就是結構 (struct) 出場的時機啦!
以昨天的範例來說 myFavorite 裡面有 fruit.animal.dessert.weather 但我喜歡的東西有太多太多了 color,member,month...等,如果你要調查每個人喜歡東西的名單,雖然也可以使用 map ,但這樣你每搜集一個人的資料,就要重複建立一樣的 key ,其實是非常費力的,所以結構這不就來了嗎~~只要把這些資料都收在一個單獨的結構中,我們就可以自由地調整或是控制它。
簡而言之, 結構 (struct) 是一種自訂型別,你可以對結構命名,也可以指定 欄位 (field) 名稱與其的型別。
type <結構型別的名稱> struct {
<欄位 1> <型別>
<欄位 2> <型別>
<欄位 3> <型別>
...
<欄位 N> <型別>
}
欄位是結構的變數,欄位名稱需是獨一無二的,且欄位與型別需寫在大括號之間,但型別就沒有限制,無論是指標、集合、或是其他結構也行。
讀取結構欄位和對欄位賦值:
<結構變數名稱>.<欄位名稱>
如果大家有學習過其他程式語言,或許有聽說過 物件導向程式設計語言
一詞, Go 語言雖然不是物件導向程式設計語言,但是結構卻是一個很接近物件導向程式設計語言 類別 (class) 的東西,但與類別不同的是 結構無法被繼承 。
雖然 Go 語言不是物件導向語言,但我們還是經常把結構稱為物件,且將其欄位稱為屬性(就連 Go 的官方文件也是這樣稱呼的)。
當定義好結構型別就可以將其用來建立變數,接下來我們使用範例來練習建立變數吧!
範例 2:
package main
import "fmt"
type myFavorite struct { // 定義一個名為 myFavorite 的結構型別
name string // 定義結構裡的欄位名稱與型別
color string
isCommon bool
month int
}
func getFavorites() []myFavorite {
userA := myFavorite{
color: "yellow", // 有欄位名稱的賦值(可不用照順序)
isCommon: true,
name: "Krystal",
month: 12,
}
userB := myFavorite{
name: "Andy", // 有欄位名稱的賦值,沒有賦值的欄位會是零值
month: 8,
}
userC := myFavorite{
"Coco", // 沒有欄位名稱的賦值(一定要照順序)
"blue",
false,
1,
}
var userD myFavorite // 先定義一個 userD 結構變數
userD.name = "Tom" // 使用 結構變數.欄位名稱 來賦值
userD.color = "gray"
userD.isCommon = true
userD.month = 7
return []myFavorite{userA, userB, userC, userD}
}
func main() {
favorites := getFavorites()
for i := 0; i < len(favorites); i++ {
fmt.Println(i,favorites[i])
}
}
範例 2(執行結果):
0 {Krystal yellow true 12}
1 {Andy false 8}
2 {Coco blue false 1}
3 {Tom gray true 7}
今天簡單介紹了在 Go 語言中自訂型別以及結構的定義,那明天我們繼續深入來了解一下,結構還有哪些其他用法,明天見~